﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;

namespace DotNetCommon
{
    /// <summary>
    /// 表达式帮助类
    /// </summary>
    public static class ExpressionHelper
    {
        /// <summary>
        /// 返回属性名称集合，示例：
        /// <list type="bullet">
        /// <item>
        /// <code>
        /// var cols = ExpressionHelper.GetAccessNames(p => new{ p.Id,p.Name });// 输出: ["Id","Name"]
        /// </code>
        /// </item>
        /// <item>
        /// <code>
        /// var cols = ExpressionHelper.GetAccessNames(p => p.Id);// 输出: ["Id"]
        /// </code>
        /// </item>
        /// </list>
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="expression"></param>
        /// <returns></returns>
        public static List<string> GetAccessNames<T>(Expression<Func<T, object>> expression)
        {
            var cols = new List<string>();
            if (expression.NodeType != ExpressionType.Lambda) throw new Exception("无效的表达式类型!");
            var body = expression.Body;
            if (body.NodeType == ExpressionType.New)
            {
                var newExp = body as NewExpression;
                var args = newExp.Arguments;
                if (args.Count == 0) throw new Exception("必须指定列!");
                for (int i = 0; i < args.Count; i++)
                {
                    var arg = args[i];
                    if (arg.NodeType != ExpressionType.MemberAccess) throw new Exception($"无效的表达式类型: {arg}");
                    var memberExp = arg as MemberExpression;
                    var col = memberExp.Member.Name;
                    cols.Add(col);
                }
            }
            else if (body.NodeType == ExpressionType.Convert)
            {
                var unaryExp = body as UnaryExpression;
                var operandExp = unaryExp.Operand;
                if (operandExp.NodeType == ExpressionType.MemberAccess)
                {
                    var memberExp = operandExp as MemberExpression;
                    var col = memberExp.Member.Name;
                    cols.Add(col);
                }
                else
                {
                    throw new Exception("无效的表达式类型!");
                }
            }
            else if (body.NodeType == ExpressionType.MemberAccess)
            {
                var memberExp = body as MemberExpression;
                var col = memberExp.Member.Name;
                cols.Add(col);
            }
            else
            {
                throw new Exception("无效的表达式类型!");
            }
            return cols;
        }
    }
}
